%% Copyright
-module(cn2p_catalog).
-author("").

-include_lib("erlastic_search/include/erlastic_search.hrl").

%% API
-export([start_link/2,
         add_product/1,
         get_product/1,
         get_product_review/2,
         get_product_details/1,
         get_product_reviews/3,
         add_product_review/2,
         search_product_by_id/1,
         search_product_by_tag/3,
         search_product_by_name/3,
         update_product_review/3,
         get_tags/0,
         product_exists/1,
         review_exists/1,
         delete_products_and_reviews/0]).

%%====================================================================
%% API
%%====================================================================

start_link(couchdb, StoreContext) ->
  gen_server:start_link({local, ?MODULE}, couchdb_catalog, StoreContext, []);

start_link(riak, StoreContext) ->
  gen_server:start_link({local, ?MODULE}, riak_catalog, StoreContext, []).

add_product(Product) ->
  gen_server:call(?MODULE, {add_product, Product}).

get_product(ProductId) ->
  gen_server:call(?MODULE, {get_product, ProductId}).

get_product_details(ProductId) ->
  gen_server:call(?MODULE, {get_product_details, ProductId}).

add_product_review(ProductId, Review) ->
  gen_server:call(?MODULE, {add_product_review, ProductId, Review}).

get_product_review(ProductId, ReviewId) ->
  gen_server:call(?MODULE, {get_product_review, ProductId, ReviewId}).

update_product_review(ProductId, ReviewId, ReviewUpdate) ->
  gen_server:call(?MODULE, {update_product_review, ProductId, ReviewId, ReviewUpdate}).

get_product_reviews(ProductId, PageIndex, PageSize) ->
  gen_server:call(?MODULE, {get_product_reviews, ProductId, PageIndex, PageSize}).

product_exists(ProductId) ->
  gen_server:call(?MODULE, {product_exists, ProductId}).

review_exists(ReviewId) ->
  gen_server:call(?MODULE, {review_exists, ReviewId}).

get_tags() ->
  gen_server:call(?MODULE, {get_tags}).

search_product_by_id(Keys) ->
  gen_server:call(?MODULE, {search_product, id, Keys}).

search_product_by_tag(Tag, PageIndex, PageSize) ->
  gen_server:call(?MODULE, {search_product, tag, Tag, {PageIndex, PageSize}}).

search_product_by_name(Name, PageIndex, PageSize) ->
  {ok, {Host, Port, IndexName}} = application:get_env(cn2p_product_catalog_service, elasticsearch),
  ErlsParams = #erls_params{ host = list_to_binary(Host), port = Port },

  case erlastic_search:search(ErlsParams,
                              list_to_binary(IndexName),
                              list_to_binary(IndexName),
                              <<"prodName:", Name/binary>>,
                              [{<<"from">>, integer_to_list(PageIndex)},
                               {<<"size">>, integer_to_list(PageSize)}]) of
    {ok, [_, _, _, {_, Hits}]} ->
      [{_, TotalCount}, _, {_, Docs}] = Hits,
      FoldFun = fun([_, _, _, _, {_, Doc}], Acc) ->
        {PreparedDoc} = couchdb_catalog:prepare_product_doc({Doc}),
        [PreparedDoc | Acc]
      end,

      {ok, [{<<"totalCount">>, binary_util:integer_to_binary(TotalCount)},
            {<<"products">>, lists:reverse(lists:foldl(FoldFun, [], Docs))}]};

    _ ->
      {ok, [{<<"totalCount">>, <<"0">>}, {<<"products">>, <<"">>}]}
  end.

delete_products_and_reviews() ->
  gen_server:call(?MODULE, {delete_all}).
